package com.weike.bsp

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.config.web.server.invoke
import org.springframework.security.core.authority.AuthorityUtils
import org.springframework.security.core.userdetails.ReactiveUserDetailsService
import org.springframework.security.web.server.SecurityWebFilterChain
import org.springframework.security.web.server.header.XFrameOptionsServerHttpHeadersWriter


@EnableWebFluxSecurity
@Configuration
class WebFluxSecurityConfig {

    @Bean
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
//        http
//                .authorizeExchange()
//                .anyExchange()
//                .authenticated()
//                .and()
//                .httpBasic().and()
//                .formLogin()

        return http {
//            addFilterAt()
            authorizeExchange {
                authorize("/login", permitAll)
                authorize("/register", permitAll)
                authorize("/verifyCode", permitAll)
                authorize(access = authenticated)
            }

            anonymous {
                authorities = AuthorityUtils.createAuthorityList("ANONYMOUS")
            }
//            formLogin {
//                authenticationEntryPoint = ServerAuthenticationEntryPoint { exchange, ex ->
//                    return@ServerAuthenticationEntryPoint exchange.response.setComplete() //Mono.fromRunnable(() -> exchange.getResponse().setStatusCode(this.httpStatus))
//                }
//                authenticationFailureHandler = ServerAuthenticationFailureHandler { webFilterExchange, exception ->
//                    return@ServerAuthenticationFailureHandler webFilterExchange.exchange.response.setComplete()
//                }
//
//                authenticationSuccessHandler = ServerAuthenticationSuccessHandler {webFilterExchange, authentication ->
//                    return@ServerAuthenticationSuccessHandler webFilterExchange.exchange.response.setComplete()
//                }
//            }
            logout {
//                logoutSuccessHandler = ServerLogoutSuccessHandler { exchange, authentication ->
//                    return@ServerLogoutSuccessHandler exchange.exchange.response.setComplete()
//                }
                disable()
            }

            headers {
                frameOptions {
                    mode = XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN
                }
            }
            csrf {
                disable()
            }
        }

//        return http.build()
    }

    @Bean
    fun reactiveAuthenticationManager(userDetailsService: ReactiveUserDetailsService): UserDetailsRepositoryReactiveAuthenticationManager {
        return UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService)
    }

//    @Bean
//    fun userDetailsService(): MapReactiveUserDetailsService {
//        val user = User.builder()
//                .username("user")
//                .password("password")
//                .roles("USER")
//                .build()
//        return MapReactiveUserDetailsService(user)
//    }
}